/**
 * 将数组中的数据进行迭代处理
 * @param {func} fn 对迭代的数据进行处理的操作
 * @param  {...any} args 需要进行处理的数据
 */
const reduce = (fn, async) => {
  if (async) {
    return function(...args) {
      return args.reduce((a, b) => {
        return Promise.resolve(a).then(v => {
          return fn.call(this, v, b)
        })
      })
    }
  } else {
    return function(...args) {
      return args.reduce(fn.bind(this))
    }
  }
}

/**
 * 加法运算
 * @param {float} x 加数
 * @param {float} y 加数
 */
let add = (x, y) => {
  return x + y
}
add = reduce(add)

/**
 * 乘法操作
 * @param {float} x 乘数
 * @param {float} y 乘数
 */
let mul = (x, y) => {
  return x * y
}
mul = reduce(mul)
/**
 * 数组拼接操作
 * @param {float} x 数组
 * @param {float} y 数组
 */
let concat = (x, y) => {
  return x.concat(y)
}
concat = reduce(concat)

let asyncAdd = (x, y) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      return resolve(x + y)
    }, 1000)
  })
}

asyncAdd = reduce(asyncAdd, true)

asyncAdd(1, 2, 3).then(result => {
  console.log(result)
})

// 抛出
export { add, mul, concat }
